//
//  TArray.c
//  TDA
//
//

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "TArray.h"

#define GROWING_DELTA 10
#define SHRINKING_DELTA 20

void array_resize(TArray *arr, int new_length);

//Definizione della struttura rappresentante l'array dinamico
struct SArray
{
   TInfo *item;
   int length; //Riempimento
   int size; //Dimensione allocata
};

//Consente di creare un array con una determinata lunghezza iniziale
TArray* array_create(int initial_length)
{
   TArray *a;
   a = (TArray*)malloc(sizeof(TArray));
   assert(a!=NULL);
   
   a->item = (TInfo*)malloc(initial_length*sizeof(TInfo));
   assert(a->item!=NULL);
   a->length = 0;
   a->size = initial_length;
   return a;
}

//Consente di deallocare le risorse instanziate per un array
void array_destroy(TArray *arr)
{
   if(arr->item != NULL)
   {
      free(arr->item);
      arr->item = NULL;
      arr->length = 0;
      arr->size = 0;
   }
}

//Riallocazione delle dimensione di un array utilizzando l'espansione lineare
void array_resize(TArray *arr, int new_length)
{
   if(arr != NULL)
   {
      if(arr->length < new_length || arr->length > (new_length + SHRINKING_DELTA))
      {
         int new_size = new_length + GROWING_DELTA;
         arr->item = realloc(arr->item, new_size*sizeof(TInfo));
         assert(new_size != 0 || arr->item != NULL);
         arr->size = new_size;
      }
   }
   arr->length = new_length;
}

//Consente di inserire un elemento alla posizione specificata
void array_insert(TArray *arr, int position, TInfo info)
{
   array_resize(arr, arr->length+1);
   
   int i;
   for(i=arr->length; i>position; i--)
   {
      arr->item[i] = arr->item[i-1];
   }
   arr->item[position] = info;
}

//Consente di rimuovere un elemento presente nell'array
void array_remove(TArray *arr, int position)
{
   if(position < arr->length)
   {
      int i;
      for (i=position; i<arr->length-1; i++) {
         arr->item[i] = arr->item[i+1];
      }
      array_resize(arr, arr->length-1);
   }
}

//Consente di modificare il valore di un elemento nell'array
void array_set(TArray *arr, TInfo info, int position)
{
   if(position<arr->length)
   {
      arr->item[position] = info;
   }
}

//Consente di leggere un elemento di un array
TInfo* array_get(TArray *arr, int position)
{
   TInfo* info;
   if(position<arr->length)
   {
      info = (arr->item)+position;
   }
   return info;
}

//Fornisce il riempimento di un array
int array_length(TArray *arr)
{
   return arr->length;
}

//Determina l'esistenza di una certa informazione all'interno dell'array
bool array_contains(TArray *arr, TInfo info)
{
   int i = 0;
   bool found = false;
   while(i<arr->length && found == false)
   {
      if (info_are_equals(arr->item[i], info) ) {
         found = true;
      }
      i++;
   }
   
   return found;
}

/*
 Consente di scambiare l'elemento di indice i con quello di indice js
 */
void array_swap(TArray *arr, int i, int j){
    TInfo tmp;
    tmp = *array_get(arr, i);
    array_set(arr, *array_get(arr, j), i);
    array_set(arr, tmp, j);
}




